package com.cosina.game.crystallight.model.battle;

import java.util.ArrayList;
import java.util.List;

import android.graphics.Point;

import com.cosina.game.crystallight.util.World;

public class BattleFieldLoad implements BattleField{
	
	protected final int id;
	private Point[] locationsOfTower;
	private Point[] LocationsOfMenu;
	private final int[] directions;
	private final int castleDirection;
	private final Point[] castleArea;
	private Point[] sourceArea;
	private Point locationSpeed;
	private final Point locationCastle;
	
	private final int[][] rawTiles;
	private final int[][] dataMonster;
	private final int mapType;
	
	public BattleFieldLoad(int id,int[][] dataFeild){
		this.id = id;
		this.mapType = dataFeild[0][0];
		{
			this.dataMonster = new int[dataFeild.length-10][dataFeild[10].length];
			for(int y=10; y<dataFeild.length; y++){
				System.arraycopy(dataFeild[y], 0, dataMonster[y-10], 0, dataFeild[y].length);
			}
		}
		{
			this.rawTiles = new int[9][dataFeild[1].length];
			for(int y=1; y<10; y++){
				System.arraycopy(dataFeild[y], 0, rawTiles[y-1], 0, dataFeild[y].length);
			}
		}
		
		for(int i=0; i<rawTiles.length; i++){
			if(rawTiles[i][0] == -1){
				sourceArea = new Point[3];
				sourceArea[0] = new Point(0,i-1);
				sourceArea[1] = new Point(0,i);
				sourceArea[2] = new Point(0,i+1);
			}
		}
		
		{
			List<Point> locationTowerList = new ArrayList<Point>();
			List<Point> LocationMenuList = new ArrayList<Point>();
			for(int y=0; y<rawTiles.length; y++){
				for(int x=0; x<rawTiles[0].length; x++){
					if(rawTiles[y][x]>0){
						if(rawTiles[y][x]/1000 == 2){
							locationTowerList.add(new Point(x,y));
						}else if(rawTiles[y][x]/1000 == 1){
							LocationMenuList.add(new Point(x,y));
						}else if(rawTiles[y][x]/1000 == 3){
							locationSpeed = new Point(x,y);
						}
					}
				}
			}
			locationsOfTower = locationTowerList.toArray(new Point[locationTowerList.size()]);
			LocationsOfMenu = LocationMenuList.toArray(new Point[LocationMenuList.size()]);
		}
		Point startPath =  sourceArea[1];
		Point currentPath = new Point(startPath);
		
		List<Integer> directionsArray = new ArrayList<Integer>();
		for(int i=-2; true ; i--){
			if(currentPath.x<(rawTiles[0].length-1)){
				if(rawTiles[currentPath.y][currentPath.x + 1] == i){
					directionsArray.add(World.RIGHT);
					currentPath.set(currentPath.x + 1, currentPath.y);
					continue;
				}
			}if(currentPath.x > 0){
				if(rawTiles[currentPath.y][currentPath.x-1] == i){
					directionsArray.add(World.LEFT);
					currentPath.set(currentPath.x - 1, currentPath.y);
					continue;
				}
			}if(currentPath.y<(rawTiles.length-1)){
				if(rawTiles[currentPath.y+1][currentPath.x] == i){
					directionsArray.add(World.BOTTOM);
					currentPath.set(currentPath.x, currentPath.y+1);
					continue;
				}
			}if(currentPath.y > 0){
				if(rawTiles[currentPath.y-1][currentPath.x] == i){
					directionsArray.add(World.TOP);
					currentPath.set(currentPath.x, currentPath.y - 1);
					continue;
				}
			}
			{
				if(currentPath.x == (rawTiles[0].length-1)){
					castleDirection = World.LEFT;
					castleArea = new Point[3];
					castleArea[0] = new Point(currentPath.x,currentPath.y-1);
					castleArea[1] = new Point(currentPath.x,currentPath.y);
					castleArea[2] = new Point(currentPath.x,currentPath.y+1);
				}else{
					castleDirection = World.TOP;
					castleArea = new Point[3];
					castleArea[0] = new Point(currentPath.x-1,currentPath.y);
					castleArea[1] = new Point(currentPath.x,currentPath.y);
					castleArea[2] = new Point(currentPath.x+1,currentPath.y);
				}
				locationCastle = new Point(currentPath.x -1, currentPath.y-1);
				break;
			}
		}
		directions = new int[directionsArray.size()];
		for(int i=0; i<directions.length; i++){
			directions[i] = directionsArray.get(i);
		}
	}
	
	public final int getMapType(){
		return mapType;
	}
	
	@Override
	public final int[][] groudData(){
		return rawTiles;
	}
	
	
	@Override
	public Point enemyDoorLocation() {
		return sourceArea[1];
	}
	@Override
	public int[] pathDirection() {
		return directions;
	}
	@Override
	public int castleDirection() {
		return castleDirection;
	}
	
	@Override
	public Point castleLocation() {
		return locationCastle;
	}
	@Override
	public Point locationSource() {
		return sourceArea[0];
	}
	@Override
	public Point[] locationAbilities() {
		return LocationsOfMenu;
	}
	@Override
	public Point locationSpeed() {
		return locationSpeed;
	}
	
	@Override
	public Point[] defaultTowers() {
		return locationsOfTower;
	}
	@Override
	public int[][] waveKind() {
		return dataMonster;
	}
	
	public Point[] getEnemyHomeArea(){
		return sourceArea;
	}
	
	public Point[] getCastleArea(){
		return castleArea;
	}

	@Override
	public String getId() {
		return id + "";
	}
}
